package com.hopes.bizz.poll.hj212.server.handler;

import com.alibaba.fastjson.JSONObject;
import com.hopes.bizz.common.core.util.RegexUtil;
import com.hopes.bizz.poll.hj212.beans.bo.HJ212MainAttrBO;
import com.hopes.bizz.poll.hj212.constant.HJ212Constant;
import com.hopes.bizz.poll.hj212.logic.OnlineStatusLogic;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

import static com.hopes.bizz.poll.hj212.constant.HJ212Constant.*;

@Slf4j
public abstract class AbstractHJ212DataHandler implements HJ212DataHandler {

    @Override
    public boolean handler(String data, DataHandlerChain chain) throws DataHandlerException {
        if (!StringUtil.isNullOrEmpty(data)) {
            String[] dataArr = data.split("\r\n");
            for (String tempData : dataArr) {
                JSONObject dataJson = hj212DataToJSON(tempData);
                Long monitorSiteId = getMonitorSiteIdIfExist(dataJson);
                Long orgId = getMonitorSiteOrgIdIfExist(dataJson);
                if (monitorSiteId != null) {
                    String commandNo = dataJson.getString(HJ212Constant.KEY_COMMAND_NO);
                    if (StringUtil.isNullOrEmpty(commandNo)) {
                        throw new DataHandlerException(HJ212Constant.KEY_COMMAND_NO + " 不能为空");
                    }
                    // 更新数采仪最后通讯时间
                    OnlineStatusLogic.setDataClientCommunicationTime(monitorSiteId, new Date());

                    //记录最后上报时间
                    HJ212MainAttrBO mainAttrBO = new HJ212MainAttrBO();
                    buildMainAttr(mainAttrBO, dataJson, commandNo);
                    mainAttrBO.setOrgId(orgId);
                    switch (commandNo) {
                        case COMMAND_REAL_TIME_DATA:
                            handlerRealTimeData(monitorSiteId, dataJson, tempData, mainAttrBO);
                            break;
                        case COMMAND_MINUTE_DATA:
                            handlerMinuteData(monitorSiteId, dataJson, tempData, mainAttrBO);
                            break;
                        case COMMAND_HOUR_DATA:
                            handlerHourData(monitorSiteId, dataJson, tempData, mainAttrBO);
                            break;
                        case COMMAND_DAY_DATA:
                            handlerDayData(monitorSiteId, dataJson, tempData, mainAttrBO);
                            break;
                        default:
                            log.info("系统暂时无法处理该命令,CN={}", commandNo);
                            break;
                    }
                    return true;
                } else {
                    log.info("没有找到对应mn号，不作处理,MN={}", dataJson.getString(HJ212Constant.KEY_MN));
                }
            }
        }
        return chain.handler(data, chain);
    }

    /**
     * 构建主要参数
     *
     * @param mainAttrBO
     * @param dataMap
     */
    private void buildMainAttr(HJ212MainAttrBO mainAttrBO, JSONObject dataMap, String commandNo) {
        mainAttrBO.setDataTime(HJ212MainAttrBO.findDataTime(dataMap, commandNo));
        mainAttrBO.setBeginTime(HJ212MainAttrBO.findBeginTime(dataMap, commandNo));
        mainAttrBO.setEndTime(HJ212MainAttrBO.findEndTime(dataMap, commandNo));
        mainAttrBO.setMn(dataMap.getString(KEY_MN));
        mainAttrBO.setQn(dataMap.getString(KEY_REQUEST_NO));
        mainAttrBO.setCn(commandNo);
    }

    public Double getDoubleValue(String value) {
        if (!StringUtil.isNullOrEmpty(value) && RegexUtil.validateDouble(value)) {
            return Double.valueOf(value);
        }
        return null;
    }

    /**
     * 处理实时检测数据
     *
     * @param monitorSiteId
     * @param dataJson
     * @param data
     * @param mainAttrBO
     * @throws DataHandlerException
     */
    public abstract void handlerRealTimeData(Long monitorSiteId, JSONObject dataJson, String data, HJ212MainAttrBO mainAttrBO) throws DataHandlerException;

    /**
     * 处理分钟检测数据
     *
     * @param monitorSiteId
     * @param dataJson
     * @param data
     * @param mainAttrBO
     * @throws DataHandlerException
     */
    public abstract void handlerMinuteData(Long monitorSiteId, JSONObject dataJson, String data, HJ212MainAttrBO mainAttrBO) throws DataHandlerException;

    /**
     * 处理小时检测数据
     *
     * @param monitorSiteId
     * @param dataJson
     * @param data
     * @param mainAttrBO
     * @throws DataHandlerException
     */
    public abstract void handlerHourData(Long monitorSiteId, JSONObject dataJson, String data, HJ212MainAttrBO mainAttrBO) throws DataHandlerException;

    /**
     * 处理日检测数据
     *
     * @param monitorSiteId
     * @param dataJson
     * @param data
     * @param mainAttrBO
     * @throws DataHandlerException
     */
    public abstract void handlerDayData(Long monitorSiteId, JSONObject dataJson, String data, HJ212MainAttrBO mainAttrBO) throws DataHandlerException;

    /**
     * 212协议数据转换为Map对象
     *
     * @param data
     * @return
     */
    public static JSONObject hj212DataToJSON(String data) {
        return JSONObject.parseObject(data);
    }

    /**
     * 如果存在就返回返回有效的MN号
     *
     * @param dataJson
     * @return
     */
    protected abstract Long getMonitorSiteIdIfExist(JSONObject dataJson);

    protected abstract Long getMonitorSiteOrgIdIfExist(JSONObject dataJson);
}
